home *** CD-ROM | disk | FTP | other *** search
/ ETO Development Tools 4 / ETO Development Tools 4.iso / Tools - Objects / MacApp / MacApp 3.0a2 / Libraries / UControl.cp < prev    next >
Encoding:
Text File  |  1991-05-01  |  47.4 KB  |  1,800 lines  |  [TEXT/MPS ]

  1. // UControl.cp
  2. // Copyright © 1987-1991 by Apple Computer Inc.  All rights reserved.
  3.  
  4. #ifndef __UCONTROL__
  5. #include "UControl.h"
  6. #endif
  7.  
  8. #ifndef __STDLIB__
  9. #include "StdLib.h"
  10. #endif
  11.  
  12. #ifndef __USCROLLER__
  13. #include <UScroller.h>
  14. #endif
  15.  
  16. #ifndef __UMACAPPUTILITIES__
  17. #include <UMacAppUtilities.h>
  18. #endif
  19.  
  20. #ifndef __UMACAPPGLOBALS__
  21. #include <UMacAppGlobals.h>
  22. #endif
  23.  
  24. #ifndef __UADORNERS__
  25. #include <UAdorners.h>
  26. #endif
  27.  
  28. #ifndef __UITERATOR__
  29. #include <UIterator.h>
  30. #endif
  31.  
  32.  
  33. //--------------------------------------------------------------------------------------------------
  34. #pragma segment MAControlRes
  35.  
  36. pascal void ActionProcForTScrollBar(ControlHandle aCMgrControl,
  37.                                     short partCode)
  38. {
  39.     TScrollBar * aScrollBar;
  40.  
  41.     aScrollBar = (TScrollBar *)(GetCRefCon(aCMgrControl));
  42.     FailNIL(aScrollBar);                        // What else you gonna' do? 
  43.  
  44.     aScrollBar->ActionProc(partCode);
  45. }
  46.  
  47. //--------------------------------------------------------------------------------------------------
  48. #pragma segment MASelCommand
  49. pascal void TControlTracker::Initialize(void)    // override 
  50. {
  51.     inherited::Initialize();
  52.     
  53.     fControl = NULL;
  54.     fTrackNonMovement = TRUE;
  55.     fViewConstrain = FALSE;
  56. }
  57.  
  58. //--------------------------------------------------------------------------------------------------
  59. #pragma segment MASelCommand
  60.  
  61. pascal void TControlTracker::IControlTracker(TControl* theControl,
  62.                                              const VPoint& itsMouse)
  63. {
  64.     this->INoChangesTracker(cTrackingControl, NULL, theControl, theControl->GetScroller(TRUE), itsMouse);
  65. #if qDebug
  66.     if (theControl == NULL)
  67.         ProgramBreak("Control passed to IControlTracker can''t be NULL.");
  68. #endif
  69.  
  70.     fControl = theControl;
  71. }
  72.  
  73. //--------------------------------------------------------------------------------------------------
  74. #pragma segment MAFields
  75.  
  76. pascal void TControlTracker::Fields(TObject* obj)// override 
  77. {
  78.     obj->DoToField("TControlTracker", NULL, bClass);
  79.     obj->DoToField("fControl", &fControl, bObject);
  80.  
  81.     inherited::Fields(obj);
  82. }
  83.  
  84. //--------------------------------------------------------------------------------------------------
  85. #pragma segment MAOpen
  86.  
  87. pascal void TControl::Initialize(void)            // override 
  88. {
  89.     inherited::Initialize();
  90.  
  91.     fTextStyle = gSystemStyle;
  92.     fDefChoice = mOKHit;                        // ??? Is this the best default 
  93.     fHilite = FALSE;
  94.     fDimmed = FALSE;
  95.     fSizeable = TRUE;
  96.     fAdornment = 0;
  97.     fPenSize = Point(0x0001, 0x0001);            // ??? Should there be a gStdPenSize 
  98.     fInset = gZeroVRect;
  99.     fDismissesDialog = FALSE;
  100. }
  101.  
  102. //--------------------------------------------------------------------------------------------------
  103. #pragma segment MAOpen
  104.  
  105. pascal void TControl::IControl(TView* itsSuperView,
  106.                                const VPoint& itsLocation,
  107.                                const VPoint& itsSize,
  108.                                SizeDeterminer itsHSizeDet,
  109.                                SizeDeterminer itsVSizeDet)
  110. {
  111.     TDocument * itsDocument;
  112.  
  113.  
  114. #if qDebug
  115.     if ((itsSize.h > kMaxCoord) || (itsSize.v > kMaxCoord))
  116.     {
  117.         Str255 theString;
  118.         ConcatNumber("The size in pixels of a TControl cannot exceed ", kMaxCoord, theString);
  119.         ProgramBreak(theString);
  120.     }
  121. #endif
  122.  
  123.     // !!! Really need to have itsDocument come in through the parameter list (post 2.0)
  124.     // Make best guess for now.
  125.     if (itsSuperView != NULL)
  126.         itsDocument = itsSuperView->fDocument;
  127.     else
  128.         itsDocument = NULL;
  129.  
  130.     this->IView(itsDocument, itsSuperView, itsLocation, itsSize, itsHSizeDet, itsVSizeDet);
  131. }
  132.  
  133. //--------------------------------------------------------------------------------------------------
  134. #pragma segment MAOpen
  135.  
  136. pascal void TControl::IRes(TDocument* itsDocument,
  137.                            TView* itsSuperView,
  138.                            Ptr& itsParams)
  139. {
  140.     TextStyle aTextStyle;
  141.     Rect r;
  142.  
  143.     inherited::IRes(itsDocument, itsSuperView, itsParams);
  144.  
  145.     ControlTemplate& templateData = *((ControlTemplate *) itsParams);
  146.  
  147.     /* fDefChoice = mOKHit; */                    //??? This seems questionable
  148.     fPenSize = templateData.itsPenSize;
  149.     this->SetAdornment(templateData.itsAdornment, kDontRedraw);
  150.     fSizeable = templateData.isSizable;
  151.     this->HiliteState(templateData.isHilited, kDontRedraw);
  152.     this->DimState(templateData.isDimmed, kDontRedraw);
  153.     fDismissesDialog = templateData.canDismiss;
  154.     r = templateData.itsInset;
  155.     fInset = r;
  156.     SetTextStyle(aTextStyle, GetFontNum(templateData.itsFontName), templateData.itsTextFace, templateData.itsTextSize, templateData.itsTextColor);
  157.     fTextStyle = aTextStyle;
  158.  
  159.     OffsetPtrWStr(itsParams, sizeof(ControlTemplate));
  160.  
  161. #if qDebug                                            
  162.     // Any good reason besides TControl??? 
  163.     if ((fSize.h > kMaxCoord) || (fSize.v > kMaxCoord))
  164.     {
  165.         Str255 theString;
  166.         ConcatNumber("The size in pixels of a TControl cannot exceed ", kMaxCoord, theString);
  167.         ProgramBreak(theString);
  168.     }
  169. #endif
  170.  
  171. }
  172.  
  173. //--------------------------------------------------------------------------------------------------
  174. #pragma segment MAControlRes
  175.  
  176. pascal TObject* TControl::Clone(void)            // override 
  177. {
  178.     TControl * aClonedControl;
  179.  
  180.     aClonedControl = (TControl *)(inherited::Clone());
  181.  
  182.     return aClonedControl;
  183. }
  184.  
  185. //--------------------------------------------------------------------------------------------------
  186. #pragma segment MAWriteRes
  187.  
  188. pascal void TControl::WRes(ViewRsrcHandle theResource,
  189.                            Ptr& itsParams)        // override 
  190. {
  191.     short theSize;
  192.     Str255 theFont;
  193.     Rect r;
  194.  
  195.     inherited::WRes(theResource, itsParams);
  196.  
  197.     theSize = fTextStyle.tsSize;
  198.     GetPortFontInfo(fTextStyle.tsFont, theFont, theSize);
  199.  
  200.     ControlTemplate& templateData = *((ControlTemplate *) ExpandPtrWStr((Handle)theResource, itsParams, sizeof(ControlTemplate), theFont.Length()));
  201.  
  202.     templateData.itsAdornment = fAdornment;
  203.     templateData.itsPenSize = fPenSize;
  204.     templateData.isSizable = fSizeable;
  205.     templateData.isDimmed = fDimmed;
  206.     templateData.isHilited = fHilite;
  207.     templateData.canDismiss = fDismissesDialog;
  208.     r = fInset;
  209.     templateData.itsInset = r;
  210.     templateData.itsTextFace = fTextStyle.tsFace;
  211.     templateData.itsTextSize = theSize;
  212.     templateData.itsTextColor = fTextStyle.tsColor;
  213.     // itsFontName = theFont; 
  214.     CopyStr255(theFont, PRStr(templateData.itsFontName));
  215. }
  216.  
  217. //--------------------------------------------------------------------------------------------------
  218. #pragma segment MAWriteRes
  219.  
  220. pascal void TControl::WriteRes(ViewRsrcHandle theResource,
  221.                                Ptr& itsParams)    // override 
  222. {
  223.     gWResSignature = 'cntl';
  224.     gWResType = "TControl";
  225.     this->WRes(theResource, itsParams);
  226. }
  227.  
  228. //--------------------------------------------------------------------------------------------------
  229. #pragma segment MAControlRes
  230.  
  231. pascal void TControl::ComputeSize(VPoint& newSize)// override 
  232. {
  233.     inherited::ComputeSize(newSize);
  234.     if (!fSizeable)
  235.     {
  236.         // …we need to adjust the bot/right offset 
  237.         // If view is going to change size, then doesn't change control's actual size 
  238.         fInset[botRight] += newSize - fSize;
  239.     }
  240. }
  241.  
  242. //--------------------------------------------------------------------------------------------------
  243. #pragma segment MAControlRes
  244.  
  245. pascal Boolean TControl::ContainsMouse(const VPoint& theMouse)// override 
  246. {
  247.     VRect aRect;
  248.  
  249.     this->ControlArea(aRect);
  250.     return aRect.Contains(theMouse);
  251. }
  252.  
  253. //--------------------------------------------------------------------------------------------------
  254. #pragma segment MAControlRes
  255.  
  256. pascal void TControl::ControlArea(VRect& theArea)
  257. {
  258.     theArea = VRect(fInset[topLeft], fSize - fInset[botRight]);
  259.     if (IN(fAdornment, adnShadow))
  260.         theArea[botRight] -= VPoint(fPenSize);
  261. }
  262.  
  263. //--------------------------------------------------------------------------------------------------
  264. #pragma segment MAControlRes
  265.  
  266. pascal void TControl::Dim(void)
  267. {
  268.     VRect area;
  269.     Rect qdArea;
  270.  
  271. #if qDebug
  272.     this->AssumeFocused();
  273. #endif
  274.     this->ControlArea(area);
  275.     this->ViewToQDRect(area, qdArea);
  276.     PenPat(qd.gray);
  277.     PenMode(patBic);
  278.     PaintRect(qdArea);
  279. }
  280.  
  281. //--------------------------------------------------------------------------------------------------
  282. #pragma segment MANonRes
  283.  
  284. pascal void TControl::DimState(Boolean state,
  285.                                Boolean redraw)
  286. {
  287.     if (state != fDimmed)
  288.     {
  289.         fDimmed = state;
  290.         if (state)                                // dim adorner draws the dim state 
  291.             this->AddAdorner(gDimAdorner, kLowestAdornPriority - 10, kDontRedraw);
  292.         else
  293.             this->DeleteAdorner(gDimAdorner, kDontRedraw);
  294.         if (redraw)
  295.             this->DrawContents();                // Draw change immediately 
  296.     }
  297. }
  298.  
  299. //--------------------------------------------------------------------------------------------------
  300. #pragma segment MASelCommand
  301.  
  302. pascal void TControl::DoMouseCommand(VPoint& theMouse,
  303.                                      TToolboxEvent* ,
  304.                                      Point)    // override 
  305. {
  306.     TControlTracker * aControlTracker;
  307.  
  308.     aControlTracker = new TControlTracker;
  309.     aControlTracker->IControlTracker(this, theMouse);
  310.     this->PostCommand(aControlTracker);
  311. }
  312.  
  313. //--------------------------------------------------------------------------------------------------
  314. #pragma segment DlgRes
  315.  
  316. pascal void TControl::Flash(void)
  317. {
  318.     long dontCare;
  319.  
  320.     this->HiliteState(TRUE, kRedraw);
  321.     Delay(8, dontCare);
  322.     this->HiliteState(FALSE, kRedraw);
  323. }
  324.  
  325. //--------------------------------------------------------------------------------------------------
  326. #pragma segment MAControlRes
  327.  
  328. pascal Boolean TControl::Focus(void)            // override 
  329. {
  330.     TextStyle aTextStyle;
  331.  
  332.     if (inherited::Focus())
  333.     {
  334.         aTextStyle = fTextStyle;
  335.         SetPortTextStyle(aTextStyle);
  336.         PenNormal();
  337.         return TRUE;
  338.     }
  339.     else
  340.         return FALSE;
  341. }
  342.  
  343. //--------------------------------------------------------------------------------------------------
  344. #pragma segment MAControlRes
  345.  
  346. pascal void TControl::Hilite(void)
  347. {
  348.     VRect area;
  349.     Rect qdArea;
  350.  
  351. #if qDebug
  352.     this->AssumeFocused();
  353. #endif
  354.     this->ControlArea(area);
  355.     this->ViewToQDRect(area, qdArea);
  356.     InvertRect(qdArea);
  357. }
  358.  
  359. //--------------------------------------------------------------------------------------------------
  360. #pragma segment MANonRes
  361.  
  362. pascal void TControl::HiliteState(Boolean state,
  363.                                   Boolean redraw)
  364. {
  365.     if (state != fHilite)
  366.     {
  367.         fHilite = state;
  368.         if (state)                                // hilite adorner draws the hilite state 
  369.             this->AddAdorner(gHiliteAdorner, kLowestAdornPriority - 5, kDontRedraw);
  370.         else
  371.             this->DeleteAdorner(gHiliteAdorner, kDontRedraw);
  372.         if (redraw && this->IsDrawable())
  373.             this->Hilite();
  374.     }
  375. }
  376.  
  377. //--------------------------------------------------------------------------------------------------
  378. #pragma segment MANonRes
  379.  
  380. pascal void TControl::Inset(short dh,
  381.                             short dv,
  382.                             Boolean redraw)
  383. {
  384.     if (fSizeable)
  385.     {
  386.         fInset += VPoint(dv, dh);
  387.         this->Resize(fSize.Copy(), redraw);
  388.     }
  389. }
  390.  
  391. //--------------------------------------------------------------------------------------------------
  392. #pragma segment MANonRes
  393.  
  394. pascal void TControl::InstallColor(const RGBColor& theColor,
  395.                                    Boolean redraw)
  396. {
  397.     fTextStyle.tsColor = theColor;
  398.     if (redraw)
  399.         this->DrawContents();
  400. }
  401.  
  402.  
  403. //--------------------------------------------------------------------------------------------------
  404. #pragma segment MANonRes
  405.  
  406. pascal void TControl::InstallTextStyle(const TextStyle& theTextStyle,
  407.                                        Boolean redraw)
  408. {
  409.     fTextStyle = theTextStyle;
  410.     if (redraw)
  411.         this->DrawContents();
  412. }
  413.  
  414. //--------------------------------------------------------------------------------------------------
  415. #pragma segment MAControlRes
  416.  
  417. pascal Boolean TControl::IsDimmed(void)
  418. {
  419.     return fDimmed;
  420. }
  421.  
  422. //--------------------------------------------------------------------------------------------------
  423. #pragma segment MANonRes
  424.  
  425. pascal void TControl::Resize(const VPoint& newSize,
  426.                              Boolean invalidate)// override 
  427. {
  428.     // If we need to invalidate, then invalidate the whole view rather than
  429.     // the difference between the old and new size.
  430.     inherited::Resize(newSize, invalidate);
  431.     
  432.     if (invalidate)
  433.         this->ForceRedraw();
  434. }
  435.  
  436. //--------------------------------------------------------------------------------------------------
  437. #pragma segment MAControlRes
  438.  
  439. pascal void TControl::GetAdornExtent(VRect& itsAdornExtent)// override 
  440. {
  441.     // NOTE: for compatibility with MacApp 2.0, this doesn't inset the extent by fInset 
  442.  
  443.     this->GetExtent(itsAdornExtent);
  444.  
  445.     if (IN(fAdornment, adnShadow))    // account for shadowing 
  446.         itsAdornExtent[botRight] -= VPoint(fPenSize);
  447. }
  448.  
  449. //--------------------------------------------------------------------------------------------------
  450. #pragma segment MANonRes
  451.  
  452. pascal TAdornment* TControl::MakeAdornment(void)
  453. {
  454.     fViewAdornment = inherited::MakeAdornment();
  455.     fViewAdornment->fPenSize = fPenSize;
  456.     return fViewAdornment;
  457. }
  458.  
  459. //--------------------------------------------------------------------------------------------------
  460. #pragma segment MANonRes
  461.  
  462. pascal void TControl::SetAdornment(/* CntlAdornment */ short newAdornment,
  463.                                    Boolean redraw)
  464. {
  465.     if (fAdornment != newAdornment)
  466.     {
  467.         fAdornment = newAdornment;
  468.  
  469.         // parse newAdornment adding adorners as needed 
  470.         if ((newAdornment & kFrame) == kFrame)                // kFrame 
  471.         {
  472.             this->DeleteAdornerByID(kLineTopAdorner, redraw);
  473.             this->DeleteAdornerByID(kLineLeftAdorner, redraw);
  474.             this->DeleteAdornerByID(kLineBottomAdorner, redraw);
  475.             this->DeleteAdornerByID(kLineRightAdorner, redraw);
  476.             this->AddAdorner( NewStdAdorner(kFrameAdorner,"",kFrameAdorner,kFreeOnDeletion), 
  477.                                 kLowestAdornPriority - 15, redraw);
  478.         }
  479.         else
  480.         {
  481.             this->DeleteAdornerByID(kFrameAdorner, redraw);
  482.             if (IN(newAdornment, adnLineTop))// adnLineTop 
  483.                 this->AddAdorner( NewStdAdorner(kLineTopAdorner,"",kLineTopAdorner,kFreeOnDeletion), 
  484.                                     kLowestAdornPriority - 15, redraw);
  485.             else
  486.                 this->DeleteAdornerByID(kLineTopAdorner, redraw);
  487.             if (IN(newAdornment, adnLineLeft))// adnLineLeft 
  488.                 this->AddAdorner( NewStdAdorner(kLineLeftAdorner,"", kLineLeftAdorner, kFreeOnDeletion), 
  489.                                     kLowestAdornPriority - 15, redraw);
  490.             else
  491.                 this->DeleteAdornerByID(kLineLeftAdorner, redraw);
  492.             if (IN(newAdornment, adnLineBottom))// adnLineBottom 
  493.                 this->AddAdorner( NewStdAdorner(kLineBottomAdorner,"", kLineBottomAdorner, kFreeOnDeletion), 
  494.                                     kLowestAdornPriority - 15, redraw);
  495.             else
  496.                 this->DeleteAdornerByID(kLineBottomAdorner, redraw);
  497.             if (IN(newAdornment, adnLineRight))// adnLineRight
  498.                 this->AddAdorner( NewStdAdorner(kLineRightAdorner,"", kLineRightAdorner, kFreeOnDeletion), 
  499.                                     kLowestAdornPriority - 15,  redraw);
  500.             else
  501.                 this->DeleteAdornerByID(kLineRightAdorner, redraw);
  502.         }
  503.  
  504.  
  505.         if (IN(newAdornment, adnOval))// adnOval
  506.             this->AddAdorner( NewStdAdorner(kOvalAdorner, "", kOvalAdorner, kFreeOnDeletion), 
  507.                                 kLowestAdornPriority - 20,  redraw);
  508.         else
  509.             this->DeleteAdornerByID(kOvalAdorner, redraw);
  510.  
  511.         if (IN(newAdornment, adnRRect))// adnRRect
  512.             this->AddAdorner( NewStdAdorner(kRRectAdorner, "", kRRectAdorner, kFreeOnDeletion),
  513.                                 kLowestAdornPriority - 20,  redraw);
  514.         else
  515.             this->DeleteAdornerByID(kRRectAdorner, redraw);
  516.  
  517.         fViewAdornment = this->MakeAdornment();    // Make sure we have one
  518.         if (IN(newAdornment, adnShadow))// adnShadow
  519.             fViewAdornment->fDrawShadow = TRUE;
  520.         else
  521.             fViewAdornment->fDrawShadow = FALSE;
  522.  
  523.         if (redraw)
  524.             this->ForceRedraw();
  525.     }
  526. }
  527.  
  528. //--------------------------------------------------------------------------------------------------
  529. #pragma segment MANonRes
  530.  
  531. pascal void TControl::SetInset(const VRect& newInset,
  532.                                Boolean redraw)
  533. {
  534.     if (fSizeable)
  535.     {
  536.         fInset = newInset;
  537.         this->Resize(fSize.Copy(), redraw);
  538.     }
  539. }
  540.  
  541. //--------------------------------------------------------------------------------------------------
  542. #pragma segment MASelCommand
  543.  
  544. pascal void TControl::TrackFeedback(TrackPhase aTrackPhase,
  545.                                         const VPoint& anchorPoint,
  546.                                         const VPoint& previousPoint,
  547.                                         const VPoint& nextPoint,
  548.                                         Boolean mouseDidMove,
  549.                                         Boolean turnItOn)
  550.  
  551. {
  552. // do nothing
  553. }
  554.  
  555. //--------------------------------------------------------------------------------------------------
  556. #pragma segment MASelCommand
  557.  
  558. pascal void TControl::TrackMouse(TrackPhase aTrackPhase,
  559.                                  VPoint&,        // anchorPoint
  560.                                  VPoint&,        // previousPoint
  561.                                  VPoint& nextPoint,
  562.                                  Boolean)        // mouseDidMove
  563. {
  564.     switch (aTrackPhase)
  565.     {
  566.         case trackBegin:
  567.             this->HiliteState(TRUE, kRedraw);
  568.             break;
  569.         case trackContinue:
  570.             this->HiliteState(this->ContainsMouse(nextPoint), kRedraw);
  571.             break;
  572.         case trackEnd:
  573.             if (fHilite)
  574.                 this->HiliteState(FALSE, kRedraw);
  575.             if (this->ContainsMouse(nextPoint))
  576.                 this->HandleEvent(fDefChoice, this, NULL);
  577.             break;
  578.     }
  579. }
  580.  
  581. //--------------------------------------------------------------------------------------------------
  582. #pragma segment MAControlRes
  583.  
  584. pascal long TControl::Validate(void)
  585. {
  586.     return noErr;
  587. }
  588.  
  589. //--------------------------------------------------------------------------------------------------
  590. #pragma segment MAFields
  591.  
  592. pascal void TControl::Fields(TObject* obj)        // override 
  593. {
  594.     obj->DoToField("TControl", NULL, bClass);
  595.     obj->DoToField("fDefChoice", &fDefChoice, bInteger);
  596.     obj->DoToField("fHilite", &fHilite, bBoolean);
  597.     obj->DoToField("fDimmed", &fDimmed, bBoolean);
  598.     obj->DoToField("fSizeable", &fSizeable, bBoolean);
  599.     obj->DoToField("fDismissesDialog", &fDismissesDialog, bBoolean);
  600.     obj->DoToField("fAdornment", &fAdornment, bCntlAdornment);
  601.     obj->DoToField("fPenSize", &fPenSize, bPoint);
  602.     obj->DoToField("fInset", &fInset, bRect);
  603.     obj->DoToField("fTextStyle", &fTextStyle, bTextStyle);
  604.  
  605.     inherited::Fields(obj);
  606. }
  607.  
  608. //--------------------------------------------------------------------------------------------------
  609. #pragma segment MAOpen
  610.  
  611. pascal void TCtlMgr::Initialize(void)            // override 
  612. {
  613.     inherited::Initialize();
  614.     fCMgrControl = NULL;
  615.  
  616.     // These MUST be initialized because SetLongValues tests each new value against 
  617.     // the old value before doing anything.    If the fLongMax value should happen to 
  618.     // have a (bogus - uninitialized) value that matches itsMax, fBitsToShift won't 
  619.     // be initialized and the control manager control will behave erratically. 
  620.     fBitsToShift = 0;
  621.     fLongVal = 0;
  622.     fLongMin = 0;
  623.     fLongMax = 0;
  624. }
  625.  
  626. //--------------------------------------------------------------------------------------------------
  627. #pragma segment MAOpen
  628.  
  629. pascal void TCtlMgr::ICtlMgr(TView* itsSuperView,
  630.                              const VPoint& itsLocation,
  631.                              const VPoint& itsSize,
  632.                              SizeDeterminer itsHSizeDet,
  633.                              SizeDeterminer itsVSizeDet,
  634.                              const Str255& itsTitle,
  635.                              long itsVal,
  636.                              long itsMin,
  637.                              long itsMax,
  638.                              short itsProcID)
  639. {
  640.     VRect itsBounds;
  641.  
  642.     this->IControl(itsSuperView, itsLocation, itsSize, itsHSizeDet, itsVSizeDet);
  643.     this->ControlArea(itsBounds);
  644.     this->CreateCMgrControl(itsBounds, itsTitle, itsVal, itsMin, itsMax, itsProcID);
  645. }
  646.  
  647. //--------------------------------------------------------------------------------------------------
  648. #pragma segment MAOpen
  649.  
  650. pascal void TCtlMgr::IRes(TDocument* itsDocument,
  651.                           TView* itsSuperView,
  652.                           Ptr& itsParams)
  653. {
  654.     inherited::IRes(itsDocument, itsSuperView, itsParams);
  655.     //The subclass must create the Control Manager control
  656. }
  657.  
  658. //--------------------------------------------------------------------------------------------------
  659. #pragma segment MAControlRes
  660.  
  661. pascal TObject* TCtlMgr::Clone(void)            // override 
  662. {
  663.     TCtlMgr * aClonedCtlMgr;
  664.     short itsProcID;
  665.     VRect contrlVRect;
  666.  
  667.     aClonedCtlMgr = (TCtlMgr *)(inherited::Clone());
  668.  
  669.     if (aClonedCtlMgr->fCMgrControl != NULL)
  670.     {
  671.         itsProcID = GetCVariant(aClonedCtlMgr->fCMgrControl);
  672.  
  673.         ControlRecord & recordData = **(aClonedCtlMgr->fCMgrControl);
  674.  
  675.         contrlVRect = recordData.contrlRect;
  676.         aClonedCtlMgr->CreateCMgrControl(contrlVRect, recordData.contrlTitle, recordData.contrlValue, recordData.contrlMin, recordData.contrlMax, itsProcID);
  677.     }
  678.  
  679.     return aClonedCtlMgr;
  680. }
  681.  
  682. //--------------------------------------------------------------------------------------------------
  683. #pragma segment MAWriteRes
  684.  
  685. pascal void TCtlMgr::WriteRes(ViewRsrcHandle theResource,
  686.                               Ptr& itsParams)    // override 
  687. {
  688.     // We don't write TCtlMgrs… 
  689. }
  690.  
  691. //--------------------------------------------------------------------------------------------------
  692. #pragma segment MAClose
  693.  
  694. pascal void TCtlMgr::Free(void)                    // override 
  695. {
  696.     if (fCMgrControl)
  697.     {
  698.         this->SetCMgrVisibility(FALSE);            // This insures that HideControl, which will
  699.                                                 // be called by SizeControl, doesn't do 
  700.                                                 // anything.  HideControl seems to have some 
  701.                                                 // problems with large (~> 14000x14000) 
  702.         SizeControl(fCMgrControl, 0, 0);        // Prevent CMgr from erasing the control! 
  703.         DisposeControl(fCMgrControl);
  704.         fCMgrControl = NULL;                    // So BeInPort and others will be happy! 
  705.     }
  706.     inherited::Free();
  707. }
  708.  
  709. //--------------------------------------------------------------------------------------------------
  710. #pragma segment MANonRes
  711.  
  712. pascal void TCtlMgr::BeInPort(GrafPtr itsPort)    // override 
  713. {
  714.     if (fCMgrControl)
  715.     {
  716.         ControlRecord & recordData = **fCMgrControl;
  717.         if (!itsPort)
  718.         {
  719.             this->SetCMgrVisibility(FALSE);
  720.             recordData.contrlOwner = (WindowPtr)gWorkPort;
  721.         }
  722.         else
  723.         {
  724.             this->SetCMgrVisibility(TRUE);
  725.             recordData.contrlOwner = (WindowPtr)itsPort;
  726.         }
  727.     }
  728. }
  729.  
  730. //--------------------------------------------------------------------------------------------------
  731. #pragma segment MAOpen
  732.  
  733. pascal void TCtlMgr::CreateCMgrControl(const VRect& itsBounds,
  734.                                        const Str255& itsTitle,
  735.                                        long itsVal,
  736.                                        long itsMin,
  737.                                        long itsMax,
  738.                                        short itsProcID)
  739. {
  740.     GrafPtr itsPort;
  741.     ControlHandle aCMgrControl;
  742.     FailInfo fi;
  743.  
  744.     itsPort = this->GetGrafPort();
  745.     if (!itsPort)
  746.         itsPort = gWorkPort;
  747.     if (fi.Try())
  748.     {
  749.         Rect qdRect;
  750.         this->ViewToQDRect(itsBounds, qdRect);
  751.         aCMgrControl = NewControl(itsPort, qdRect, itsTitle, FALSE, 0, 0, 0, itsProcID, (long)this);
  752.         FailNIL(aCMgrControl);
  753.         fi.Success();
  754.     }
  755.     else    // Recover
  756.     {
  757.         this->Free();
  758.         fi.ReSignal();
  759.     }
  760.     // Keep control off Window's control list b/c the Window Mgr adds the regions of controls in
  761.     // the control list to the update region (see NOTE under DrawControls in Inside Mac volume I)
  762.     // generating an update event.
  763.  
  764.     WindowRecord& windowData = *((WindowRecord *) itsPort);
  765.     windowData.controlList = (*(windowData.controlList))->nextControl;
  766.  
  767.     fCMgrControl = aCMgrControl;
  768.     this->DimState(fDimmed, kDontRedraw);
  769.  
  770.     // Remember, the control was created with zeros, fix it up.
  771.     this->SetLongValues(itsVal, itsMin, itsMax, kDontRedraw);
  772.  
  773.     this->SetCMgrVisibility(itsPort != gWorkPort);
  774. }
  775.  
  776. //--------------------------------------------------------------------------------------------------
  777. #pragma segment MANonRes
  778.  
  779. class CCtlMgrHiliter
  780. {
  781.     // Fields
  782.     TCtlMgr* fCtlMgr;
  783.     const Boolean& fState;
  784.  
  785. public:
  786.     // Constructor
  787.     CCtlMgrHiliter(TCtlMgr* theCtlMgr,
  788.               const Boolean& theState) :
  789.         fCtlMgr(theCtlMgr),
  790.         fState(theState)
  791.     {
  792.     }
  793.  
  794.     // Method
  795.     pascal void SetToDim(void);
  796.     pascal void SetToHilite(void);
  797. };
  798.  
  799. #pragma segment MANonRes
  800.  
  801. pascal void CCtlMgrHiliter::SetToDim(void)
  802. {
  803.     HiliteControl(fCtlMgr->fCMgrControl, fState * 255);
  804.     fCtlMgr->fDimmed = fState;
  805. }
  806.  
  807. #pragma segment MANonRes
  808.  
  809. pascal void CCtlMgrHiliter::SetToHilite(void)
  810. {
  811.     HiliteControl(fCtlMgr->fCMgrControl, fState * 10);
  812. }
  813.  
  814. #pragma segment MANonRes
  815.  
  816. pascal void TCtlMgr::DimState(Boolean state,
  817.                               Boolean redraw)    // override 
  818. {
  819.     CCtlMgrHiliter aCtlMgrHiliter(this, state);
  820.  
  821.     //!!! Temporary kludge //if (fDimmed != state)
  822.         this->WhileFocused((DoWhileFocusedType) & CCtlMgrHiliter::SetToDim, &aCtlMgrHiliter, redraw);
  823.     fDimmed = state;
  824. }
  825.  
  826. //--------------------------------------------------------------------------------------------------
  827. #pragma segment MASelCommand
  828.  
  829. pascal void TCtlMgr::DoMouseCommand(VPoint& theMouse,
  830.                                     TToolboxEvent*,
  831.                                     Point) // override 
  832. {
  833.     Point theQDMouse(this->ViewToQDPt(theMouse));
  834.     
  835.     if (TestControl(fCMgrControl, theQDMouse) != 0)
  836.         if (TrackControl(fCMgrControl, theQDMouse, (ProcPtr)(-1)) != 0)
  837.             this->HandleEvent(fDefChoice, this, NULL);
  838. }
  839.  
  840. //--------------------------------------------------------------------------------------------------
  841. #pragma segment MAControlRes
  842.  
  843. pascal void TCtlMgr::Draw(const VRect& area)    // override 
  844. {
  845.     WindowPtr savedOwner;
  846.     VRect itsExtent;
  847.  
  848.     if (this->IsCMgrVisible())
  849.     {
  850.         // Set the port in case we're printing 
  851. #if qDebug
  852.         this->AssumeFocused();
  853. #endif
  854.         ControlRecord& recordData =  **fCMgrControl;
  855.         savedOwner = recordData.contrlOwner;
  856.         recordData.contrlOwner = (WindowPtr)(qd.thePort);
  857.  
  858.         PenNormal();                            // NECESSARY???
  859.         Draw1Control(fCMgrControl);
  860.  
  861.         (*fCMgrControl)->contrlOwner = savedOwner;// traps may have moved memory 
  862.     }
  863.  
  864.     inherited::Draw(area);                        // to get adornment 
  865. }
  866.  
  867. //--------------------------------------------------------------------------------------------------
  868. #pragma segment MAControlRes
  869.  
  870. pascal Boolean TCtlMgr::IsCMgrVisible(void)
  871. {
  872.     return (fCMgrControl && ((*fCMgrControl)->contrlVis == 255));
  873. }
  874.  
  875. //--------------------------------------------------------------------------------------------------
  876. #pragma segment MAControlRes
  877.  
  878. pascal short TCtlMgr::GetMax(void)
  879. {
  880.     return GetCtlMax(fCMgrControl);
  881. }
  882.  
  883. //--------------------------------------------------------------------------------------------------
  884. #pragma segment MAControlRes
  885.  
  886. pascal short TCtlMgr::GetMin(void)
  887. {
  888.     return GetCtlMin(fCMgrControl);
  889. }
  890.  
  891. //--------------------------------------------------------------------------------------------------
  892. #pragma segment MAControlRes
  893.  
  894. pascal void TCtlMgr::GetText(Str255& theText)
  895. {
  896.     theText = "";
  897.     if (fCMgrControl)
  898.         theText = (*fCMgrControl)->contrlTitle; 
  899. }
  900.  
  901. //--------------------------------------------------------------------------------------------------
  902. #pragma segment MAControlRes
  903.  
  904. pascal short TCtlMgr::GetVal(void)
  905. {
  906.     if (fCMgrControl)
  907.         return GetCtlValue(fCMgrControl);
  908.     else
  909.         return 0;
  910. }
  911.  
  912. //--------------------------------------------------------------------------------------------------
  913. #pragma segment MAControlRes
  914.  
  915. pascal short TCtlMgr::GetVariant(void)
  916. {
  917.     if (fCMgrControl)
  918.         return GetCVariant(fCMgrControl);
  919.     else
  920.         return 0;
  921. }
  922.  
  923. //--------------------------------------------------------------------------------------------------
  924. #pragma segment MANonRes
  925.  
  926. pascal void TCtlMgr::HiliteState(Boolean state,
  927.                                  Boolean redraw)// override 
  928. {
  929.     CCtlMgrHiliter aCtlMgrHiliter(this, state);
  930.  
  931.     if (fHilite != state)
  932.         this->WhileFocused((DoWhileFocusedType) & CCtlMgrHiliter::SetToHilite, &aCtlMgrHiliter, redraw);
  933.     fHilite = state;
  934. }
  935.  
  936. //--------------------------------------------------------------------------------------------------
  937. #pragma segment MANonRes
  938.  
  939. class CCtlMgrResizer
  940. {
  941.     // Fields
  942.     const VPoint& fNewSize;
  943.     TCtlMgr* fCtlMgr;
  944.  
  945. public:
  946.     // Constructor
  947.     CCtlMgrResizer(const VPoint& theNewSize,
  948.             TCtlMgr* theCtlMgr) :
  949.         fNewSize(theNewSize),
  950.         fCtlMgr(theCtlMgr)
  951.     {
  952.     }
  953.  
  954.     // Method
  955.     pascal void Resize(void);
  956. };
  957.  
  958. #pragma segment MANonRes
  959.  
  960. pascal void CCtlMgrResizer::Resize(void)
  961. {
  962.     VRect area;
  963.     fCtlMgr->ControlArea(area);
  964.  
  965.     Rect qdArea;
  966.     fCtlMgr->ViewToQDRect(area, qdArea);
  967.  
  968.     MoveControl(fCtlMgr->fCMgrControl, qdArea.left, qdArea.top);
  969.     
  970.     if (fCtlMgr->fSizeable)
  971.         SizeControl(fCtlMgr->fCMgrControl, abs(qdArea.Length(hSel)), abs(qdArea.Length(vSel)));
  972. }
  973.  
  974. //--------------------------------------------------------------------------------------------------
  975. #pragma segment MANonRes
  976.  
  977. pascal void TCtlMgr::Resize(const VPoint& newSize,
  978.                             Boolean invalidate)    // override 
  979. {
  980.     inherited::Resize(newSize, invalidate);
  981.  
  982.     CCtlMgrResizer aCtlMgrResizer(newSize, this);
  983.  
  984.     if (fSizeable && fCMgrControl)
  985.         this->WhileFocused((DoWhileFocusedType) & CCtlMgrResizer::Resize, &aCtlMgrResizer, kDontRedraw);
  986. }
  987.  
  988. //--------------------------------------------------------------------------------------------------
  989. #pragma segment MAControlRes
  990.  
  991. pascal void TCtlMgr::SetCMgrVisibility(Boolean beVisible)
  992. {
  993.     if (fCMgrControl)
  994.         if (beVisible)
  995.             (*fCMgrControl)->contrlVis = 255;
  996.         else
  997.             (*fCMgrControl)->contrlVis = 0;
  998. }
  999.  
  1000. //--------------------------------------------------------------------------------------------------
  1001. #pragma segment MAControlRes
  1002.  
  1003. class CCtlMgrValueSetter
  1004. {
  1005.     // Fields
  1006.     const short& fValue;
  1007.     ControlHandle& fCMgrControl;
  1008.  
  1009. public:
  1010.     // Constructor
  1011.     CCtlMgrValueSetter(const short& theValue,
  1012.             ControlHandle& theCMgrControl) :
  1013.         fValue(theValue),
  1014.         fCMgrControl(theCMgrControl)
  1015.     {
  1016.     }
  1017.  
  1018.     // Method
  1019.     pascal void SetMin(void);
  1020.     pascal void SetMax(void);
  1021.     pascal void SetValue(void);
  1022. };
  1023.  
  1024. #pragma segment MAControlRes
  1025.  
  1026. pascal void CCtlMgrValueSetter::SetMin(void)
  1027. {
  1028.     SetCtlMin(fCMgrControl, fValue);
  1029. }
  1030.  
  1031. #pragma segment MAControlRes
  1032.  
  1033. pascal void CCtlMgrValueSetter::SetMax(void)
  1034. {
  1035.     SetCtlMax(fCMgrControl, fValue);
  1036. }
  1037.  
  1038. #pragma segment MAControlRes
  1039.  
  1040. pascal void CCtlMgrValueSetter::SetValue(void)
  1041. {
  1042.     SetCtlValue(fCMgrControl, fValue);
  1043. }
  1044.     
  1045. #pragma segment MAControlRes
  1046.  
  1047. pascal void TCtlMgr::SetMax(short itsMax,
  1048.                             Boolean redraw)
  1049. {
  1050.     CCtlMgrValueSetter aCtlMgrValueSetter(itsMax, fCMgrControl);
  1051.  
  1052.     this->WhileFocused((DoWhileFocusedType) & CCtlMgrValueSetter::SetMax, &aCtlMgrValueSetter, redraw);
  1053. }
  1054.  
  1055. //--------------------------------------------------------------------------------------------------
  1056. #pragma segment MAControlRes
  1057.  
  1058. pascal void TCtlMgr::SetMin(short itsMin,
  1059.                             Boolean redraw)
  1060. {
  1061.     CCtlMgrValueSetter aCtlMgrValueSetter(itsMin, fCMgrControl);
  1062.  
  1063.     this->WhileFocused((DoWhileFocusedType) & CCtlMgrValueSetter::SetMin, &aCtlMgrValueSetter, redraw);
  1064. }
  1065.  
  1066. //--------------------------------------------------------------------------------------------------
  1067. #pragma segment MANonRes
  1068.  
  1069. class CCtlMgrTextSetter
  1070. {
  1071.     // Fields
  1072.     const Str255& fText;
  1073.     Str255& fCurrentText;
  1074.     Rect& fRect;
  1075.     TCtlMgr* fCtlMgr;
  1076.  
  1077. public:
  1078.     // Constructor
  1079.     CCtlMgrTextSetter(const Str255& theText,
  1080.              Str255& theCurrentText,
  1081.              Rect& theRect,
  1082.              TCtlMgr* theCtlMgr) :
  1083.         fText(theText),
  1084.         fCurrentText(theCurrentText),
  1085.         fRect(theRect),
  1086.         fCtlMgr(theCtlMgr)
  1087.     {
  1088.     }
  1089.  
  1090.     // Method
  1091.     pascal void SetText(void);
  1092. };
  1093.  
  1094. #pragma segment MANonRes
  1095.  
  1096. pascal void CCtlMgrTextSetter::SetText(void)
  1097. {
  1098.     GetCTitle(fCtlMgr->fCMgrControl, fCurrentText);
  1099.     if (fCurrentText != fText)
  1100.         SetCTitle(fCtlMgr->fCMgrControl, fText);
  1101.     fRect = (*(fCtlMgr->fCMgrControl))->contrlRect;
  1102.     if (fCtlMgr->IsFocused())
  1103.         fCtlMgr->ValidateRect(fRect);            // Because Control Manager invalidates it. 
  1104. }
  1105.  
  1106. #pragma segment MANonRes
  1107.  
  1108. pascal void TCtlMgr::SetText(const Str255& itsText,
  1109.                              Boolean redraw)
  1110. {
  1111.     Str255 currentText;
  1112.     Rect itsRect;
  1113.     CCtlMgrTextSetter aCtlMgrTextSetter(itsText, currentText, itsRect, this);
  1114.  
  1115.     this->WhileFocused((DoWhileFocusedType) &CCtlMgrTextSetter::SetText, &aCtlMgrTextSetter, redraw);
  1116. }
  1117.  
  1118. //--------------------------------------------------------------------------------------------------
  1119. #pragma segment MAControlRes
  1120.  
  1121. pascal void TCtlMgr::SetVal(short newVal,
  1122.                             Boolean redraw)
  1123. {
  1124.     CCtlMgrValueSetter aCtlMgrValueSetter(newVal, fCMgrControl);
  1125.  
  1126.     if (GetCtlValue(fCMgrControl) != newVal)
  1127.         this->WhileFocused((DoWhileFocusedType) & CCtlMgrValueSetter::SetValue, &aCtlMgrValueSetter, redraw);
  1128. }
  1129.  
  1130. //--------------------------------------------------------------------------------------------------
  1131. #pragma segment MAControlRes
  1132.  
  1133. class CCtlMgrAdjuster
  1134. {
  1135.     // Fields
  1136.     const short& fValue;
  1137.     const short& fMin;
  1138.     const short& fMax;
  1139.     ControlHandle& fCMgrControl;
  1140.  
  1141. public:
  1142.     // Constructor
  1143.     CCtlMgrAdjuster(const short& theValue,
  1144.                const short& theMin,
  1145.                const short& theMax,
  1146.                ControlHandle& theCMgrControl) :
  1147.         fValue(theValue),
  1148.         fMin(theMin),
  1149.         fMax(theMax),
  1150.         fCMgrControl(theCMgrControl)
  1151.     {
  1152.     }
  1153.  
  1154.     // Method
  1155.     pascal void SetValues(void);
  1156. };
  1157.  
  1158. #pragma segment MAControlRes
  1159.  
  1160. pascal void CCtlMgrAdjuster::SetValues(void)
  1161. {
  1162.     SetCtlMin(fCMgrControl, fMin);
  1163.     SetCtlMax(fCMgrControl, fMax);
  1164.     SetCtlValue(fCMgrControl, fValue);
  1165. }
  1166.  
  1167. #pragma segment MAControlRes
  1168.  
  1169. pascal void TCtlMgr::SetValues(short itsVal,
  1170.                                short itsMin,
  1171.                                short itsMax,
  1172.                                Boolean redraw)
  1173. {
  1174.     CCtlMgrAdjuster aCtlMgrAdjuster(itsVal, itsMin, itsMax, fCMgrControl);
  1175.  
  1176.     this->WhileFocused((DoWhileFocusedType) & CCtlMgrAdjuster::SetValues, &aCtlMgrAdjuster, redraw);
  1177. }
  1178.  
  1179. //--------------------------------------------------------------------------------------------------
  1180. #pragma segment MAControlRes
  1181.  
  1182. pascal void TCtlMgr::WhileFocused(DoWhileFocusedType DoWhileFocused,
  1183.                                   void* staticLink,
  1184.                                   Boolean redraw)
  1185. {
  1186.     Boolean wasVisible;
  1187.  
  1188.     if (fCMgrControl)
  1189.     {
  1190.         if (redraw && this->Focus())
  1191.             DoWhileFocused(staticLink);
  1192.         else
  1193.         {
  1194.             wasVisible = this->IsCMgrVisible();
  1195.             this->SetCMgrVisibility(FALSE);
  1196.             DoWhileFocused(staticLink);
  1197.             if (wasVisible && (!IsCMgrVisible()))// If DoWhileFocused didn't set it 
  1198.                 this->SetCMgrVisibility(wasVisible);// …restore visibility 
  1199.         }
  1200.     }
  1201. }
  1202.  
  1203. //--------------------------------------------------------------------------------------------------
  1204. #pragma segment MAControlRes
  1205.  
  1206. pascal VCoordinate TCtlMgr::GetLongMax(void)
  1207. {
  1208.     return fLongMax;
  1209. }
  1210.  
  1211. //--------------------------------------------------------------------------------------------------
  1212. #pragma segment MAControlRes
  1213.  
  1214. pascal VCoordinate TCtlMgr::GetLongMin(void)
  1215. {
  1216.     return fLongMin;
  1217. }
  1218.  
  1219. //--------------------------------------------------------------------------------------------------
  1220. #pragma segment MAControlRes
  1221.  
  1222. pascal VCoordinate TCtlMgr::GetLongVal(void)
  1223. {
  1224.     return fLongVal;
  1225. }
  1226.  
  1227. //--------------------------------------------------------------------------------------------------
  1228. #pragma segment MAControlRes
  1229.  
  1230. pascal void TCtlMgr::SetLongMax(VCoordinate itsMax,
  1231.                                 Boolean redraw)
  1232. {
  1233.     if (itsMax != fLongMax)
  1234.     {
  1235.         fLongMax = itsMax;
  1236.         fBitsToShift = 0;
  1237.         while (itsMax > MAXINT)
  1238.         {
  1239.             itsMax = ((itsMax) >> 1);
  1240.             ++fBitsToShift;
  1241.         }
  1242.         this->SetMax((short)itsMax, redraw);
  1243.     }
  1244. }
  1245.  
  1246. //--------------------------------------------------------------------------------------------------
  1247. #pragma segment MAControlRes
  1248.  
  1249. pascal void TCtlMgr::SetLongMin(VCoordinate itsMin,
  1250.                                 Boolean redraw)
  1251. {
  1252.     if (itsMin != fLongMin)
  1253.     {
  1254.         fLongMin = itsMin;
  1255.         this->SetMin((short)(itsMin >> fBitsToShift), redraw);
  1256.     }
  1257. }
  1258.  
  1259. //--------------------------------------------------------------------------------------------------
  1260. #pragma segment MAControlRes
  1261.  
  1262. pascal void TCtlMgr::SetLongVal(VCoordinate itsVal,
  1263.                                 Boolean redraw)
  1264. {
  1265.     itsVal = Max(fLongMin, Min(itsVal, fLongMax));
  1266.     if (itsVal != fLongVal)
  1267.     {
  1268.         fLongVal = itsVal;
  1269.         this->SetVal((short)(itsVal >> fBitsToShift), redraw);
  1270.     }
  1271. }
  1272.  
  1273. //--------------------------------------------------------------------------------------------------
  1274. #pragma segment MAControlRes
  1275.  
  1276. pascal void TCtlMgr::SetLongValues(VCoordinate itsVal,
  1277.                                    VCoordinate itsMin,
  1278.                                    VCoordinate itsMax,
  1279.                                    Boolean redraw)
  1280. {
  1281.     this->SetLongMax(itsMax, redraw);            // Must be first to get fBitsToShift setup 
  1282.     this->SetLongMin(itsMin, redraw);
  1283.     this->SetLongVal(itsVal, redraw);
  1284. }
  1285.  
  1286. //--------------------------------------------------------------------------------------------------
  1287. #pragma segment MAFields
  1288.  
  1289. pascal void TCtlMgr::Fields(TObject* obj)        // override 
  1290. {
  1291.     obj->DoToField("TCtlMgr", NULL, bClass);
  1292.     obj->DoToField("fCMgrControl", &fCMgrControl, bControlHandle);
  1293.     obj->DoToField("fBitsToShift", &fBitsToShift, bInteger);
  1294.     obj->DoToField("fLongVal", &fLongVal, bLongInt);
  1295.     obj->DoToField("fLongMin", &fLongMin, bLongInt);
  1296.     obj->DoToField("fLongMax", &fLongMax, bLongInt);
  1297.  
  1298.     inherited::Fields(obj);
  1299. }
  1300.  
  1301. //--------------------------------------------------------------------------------------------------
  1302. #pragma segment MAOpen
  1303. pascal void TScrollBar::Initialize(void)        // override 
  1304. {
  1305.     inherited::Initialize();
  1306.     fDirection = hSel;
  1307.     fDefChoice = mHScrollBarHit;
  1308. }
  1309.  
  1310. //--------------------------------------------------------------------------------------------------
  1311. #pragma segment MAOpen
  1312.  
  1313. pascal void TScrollBar::IScrollBar(TView* itsSuperView,
  1314.                                    const VPoint& itsLocation,
  1315.                                    const VPoint& itsSize,
  1316.                                    SizeDeterminer itsHSizeDet,
  1317.                                    SizeDeterminer itsVSizeDet,
  1318.                                    VHSelect itsDirection,
  1319.                                    long itsVal,
  1320.                                    long itsMin,
  1321.                                    long itsMax)
  1322. {
  1323.     this->ICtlMgr(itsSuperView, itsLocation, itsSize, itsHSizeDet, itsVSizeDet, "", itsVal, itsMin, itsMax, scrollBarProc);
  1324.     fDirection = itsDirection;
  1325.  
  1326.     if (itsDirection == hSel)
  1327.         fDefChoice = mHScrollBarHit;
  1328.     else
  1329.         fDefChoice = mVScrollBarHit;
  1330. }
  1331.  
  1332. //--------------------------------------------------------------------------------------------------
  1333. #pragma segment MAOpen
  1334.  
  1335. pascal void TScrollBar::IRes(TDocument* itsDocument,
  1336.                              TView* itsSuperView,
  1337.                              Ptr& itsParams)    // override 
  1338. {
  1339.     VRect area;
  1340.  
  1341.     inherited::IRes(itsDocument, itsSuperView, itsParams);
  1342.  
  1343.     ScrollBarTemplate& templateData = *((ScrollBarTemplate *) itsParams);
  1344.  
  1345.     this->ControlArea(area);
  1346.  
  1347.     this->CreateCMgrControl(area, "", templateData.value, templateData.minimum, templateData.maximum, scrollBarProc);
  1348.  
  1349.     if (area.Length(vSel) >= area.Length(hSel))
  1350.     {
  1351.         fDirection = vSel;
  1352.         fDefChoice = mVScrollBarHit;
  1353.     }
  1354.     else
  1355.     {
  1356.         fDirection = hSel;
  1357.         fDefChoice = mHScrollBarHit;
  1358.     }
  1359.  
  1360.     OffsetPtr(itsParams, sizeof(ScrollBarTemplate));
  1361. }
  1362.  
  1363. //--------------------------------------------------------------------------------------------------
  1364. #pragma segment MAControlRes
  1365.  
  1366. pascal TObject* TScrollBar::Clone(void)            // override 
  1367. {
  1368.     TScrollBar * aClonedScrollBar;
  1369.  
  1370.     aClonedScrollBar = (TScrollBar *)(inherited::Clone());
  1371.  
  1372.     return aClonedScrollBar;
  1373. }
  1374.  
  1375. //--------------------------------------------------------------------------------------------------
  1376. #pragma segment MAWriteRes
  1377.  
  1378. pascal void TScrollBar::WRes(ViewRsrcHandle theResource,
  1379.                              Ptr& itsParams)    // override 
  1380. {
  1381.     inherited::WRes(theResource, itsParams);
  1382.  
  1383.     ScrollBarTemplate& templateData = *((ScrollBarTemplate *) ExpandPtr((Handle)theResource, itsParams, sizeof(ScrollBarTemplate)));
  1384.  
  1385.     templateData.value = fLongVal;
  1386.     templateData.minimum = fLongMin;
  1387.     templateData.maximum = fLongMax;
  1388. }
  1389.  
  1390. //--------------------------------------------------------------------------------------------------
  1391. #pragma segment MAWriteRes
  1392.  
  1393. pascal void TScrollBar::WriteRes(ViewRsrcHandle theResource,
  1394.                                  Ptr& itsParams)// override 
  1395. {
  1396.     gWResSignature = 'sbar';
  1397.     gWResType = "TScrollBar";
  1398.     this->WRes(theResource, itsParams);
  1399. }
  1400.  
  1401. //--------------------------------------------------------------------------------------------------
  1402. #pragma segment MAControlRes
  1403.  
  1404. pascal void TScrollBar::ActionProc(short partCode)
  1405. {
  1406.     Boolean backwards;
  1407.  
  1408.     if (partCode != 0)
  1409.     {
  1410.         backwards = ((partCode == inUpButton) || (partCode == inPageUp));
  1411.  
  1412.         if ((backwards && (fLongVal > fLongMin)) || ((!backwards) && (fLongVal < fLongMax)))
  1413.             this->TrackScrollBar(partCode);
  1414.  
  1415.         this->Update();                            // Make sure that we're in synch before
  1416.                                                 // returning ??? How can this be controlable?
  1417.         this->Focus();                            // make sure i am looking at myself… e.e. cummings
  1418.     }
  1419. }
  1420.  
  1421. //--------------------------------------------------------------------------------------------------
  1422. #pragma segment MAScroll
  1423.  
  1424. pascal void TScrollBar::DeltaValue(VCoordinate delta)
  1425. {
  1426.     if (delta != 0)                                // Ensure that delta does not cause an overflow (or underflow) 
  1427.         this->SetLongVal(fLongVal + MinMax(fLongMin - fLongVal, delta, fLongMax - fLongVal), TRUE);
  1428. }
  1429.  
  1430. //--------------------------------------------------------------------------------------------------
  1431. #pragma segment MAScroll
  1432.  
  1433. pascal void TScrollBar::DoMouseCommand(VPoint& theMouse,
  1434.                                        TToolboxEvent*,
  1435.                                        Point)    // override 
  1436. {
  1437.     short partCode;
  1438.     VCoordinate oldLongValue;
  1439.     VCoordinate newLongValue;
  1440.     Point theQDMouse;
  1441.  
  1442. #if qDebug
  1443.     this->AssumeFocused();
  1444. #endif
  1445.  
  1446.     theQDMouse = this->ViewToQDPt(theMouse);
  1447.     oldLongValue = fLongVal;
  1448.  
  1449.     switch (TestControl(fCMgrControl, theQDMouse))
  1450.     {
  1451.         case inUpButton:
  1452.         case inDownButton:
  1453.         case inPageUp:
  1454.         case inPageDown:
  1455.             partCode = TrackControl(fCMgrControl, theQDMouse, (ProcPtr) & ActionProcForTScrollBar);
  1456.  
  1457.             // This method MUST inform its superview of the change! Thanks to GLB!
  1458.             if (fLongVal != oldLongValue)
  1459.                 this->HandleEvent(fDefChoice, this, NULL);
  1460.             break;
  1461.         case inThumb:
  1462.             if (TrackControl(fCMgrControl, theQDMouse, NULL) == inThumb)
  1463.             {
  1464.                 // If thumb is dragged to bottom of scroll bar then ensure that
  1465.                 // the new long value is set to the maximum long value.
  1466.                 // We get killed by side effects if we don't use a temporary variable here.
  1467.                 // This doesn't show up in the TScrollerScrollBar class because this code is
  1468.                 // overridden, but it will show up in derived classes that depend on this code
  1469.                 if (this->GetVal() == this->GetMax())
  1470.                     newLongValue = fLongMax;
  1471.                 else
  1472.                     newLongValue = ((long)GetVal() << fBitsToShift);
  1473.  
  1474.                 this->SetLongVal(newLongValue, kRedraw);
  1475.  
  1476.                 // This method MUST inform its superview of the change! 
  1477.                 if (fLongVal != oldLongValue)
  1478.                     this->HandleEvent(fDefChoice, this, NULL);
  1479.             }
  1480.             break;
  1481.     }
  1482. }
  1483.  
  1484. //--------------------------------------------------------------------------------------------------
  1485. #pragma segment MAControlRes
  1486.  
  1487. pascal void TScrollBar::TrackScrollBar(short partCode)
  1488. {
  1489.     if ((partCode == inPageUp) || (partCode == inUpButton))
  1490.         this->DeltaValue(-1);
  1491.     else
  1492.         this->DeltaValue(1);
  1493. }
  1494.  
  1495. //--------------------------------------------------------------------------------------------------
  1496. #pragma segment MAFields
  1497.  
  1498. pascal void TScrollBar::Fields(TObject* obj)    // override 
  1499. {
  1500.     obj->DoToField("TScrollBar", NULL, bClass);
  1501.     obj->DoToField("fDirection", &fDirection, bVHSelect);
  1502.  
  1503.     inherited::Fields(obj);
  1504. }
  1505.  
  1506. //--------------------------------------------------------------------------------------------------
  1507. #pragma segment MAOpen
  1508. pascal void TScrollerScrollBar::Initialize(void)// override 
  1509. {
  1510.     inherited::Initialize();
  1511.     
  1512.     fScrollers = NULL;
  1513. }
  1514.  
  1515. //--------------------------------------------------------------------------------------------------
  1516. #pragma segment MAOpen
  1517.  
  1518. pascal void TScrollerScrollBar::IScrollerScrollBar(TView* itsSuperView,
  1519.                                             const VPoint& itsLocation,
  1520.                                             const VPoint& itsSize,
  1521.                                             SizeDeterminer itsHSizeDet,
  1522.                                             SizeDeterminer itsVSizeDet,
  1523.                                             VHSelect itsDirection,
  1524.                                             long itsMax,
  1525.                                             TScroller* itsScroller)
  1526. {
  1527.     FailInfo fi;
  1528.  
  1529.     this->IScrollBar(itsSuperView, itsLocation, itsSize, itsHSizeDet, itsVSizeDet, itsDirection, 0, 0, itsMax);
  1530.     this->SetCMgrVisibility(this->IsActive());
  1531.  
  1532.     if (fi.Try())
  1533.     {
  1534.         fScrollers = NewList();
  1535. #if qDebug
  1536.         fScrollers->SetEltType("TScroller");
  1537. #endif
  1538.         this->AttachScroller(itsScroller);
  1539.         fi.Success();
  1540.     }
  1541.     else    // Recover
  1542.     {
  1543.         this->Free();
  1544.         fi.ReSignal();
  1545.     }
  1546. }
  1547.  
  1548. //--------------------------------------------------------------------------------------------------
  1549. #pragma segment MAOpen
  1550.  
  1551. pascal void TScrollerScrollBar::IRes(TDocument* itsDocument,
  1552.                                      TView* itsSuperView,
  1553.                                      Ptr& itsParams)// override 
  1554. {
  1555.     FailInfo fi;
  1556.  
  1557.     inherited::IRes(itsDocument, itsSuperView, itsParams);
  1558.     this->SetCMgrVisibility(this->IsActive());
  1559.  
  1560.     if (fi.Try())
  1561.     {
  1562.         fScrollers = NewList();
  1563. #if qDebug
  1564.         fScrollers->SetEltType("TScroller");
  1565. #endif
  1566.         fi.Success();
  1567.     }
  1568.     else    // Recover
  1569.     {
  1570.         this->Free();
  1571.         fi.ReSignal();
  1572.     }
  1573. }
  1574.  
  1575. //--------------------------------------------------------------------------------------------------
  1576. #pragma segment MAControlRes
  1577.  
  1578. pascal TObject* TScrollerScrollBar::Clone(void)    // override 
  1579. {
  1580.     TScrollerScrollBar * aScrollerScrollBar;
  1581.  
  1582.     aScrollerScrollBar = (TScrollerScrollBar *)(inherited::Clone());
  1583.  
  1584. #if qDebug
  1585.     if (aScrollerScrollBar->fScrollers->GetSize() != 1)
  1586.         ProgramBreak("###TScrollerScrollBar.Clone: Unexpected number of scrollers!");
  1587. #endif
  1588.     aScrollerScrollBar->fScrollers->DeleteAll();
  1589.  
  1590.     return aScrollerScrollBar;
  1591. }
  1592.  
  1593. //--------------------------------------------------------------------------------------------------
  1594. #pragma segment MAWriteRes
  1595.  
  1596. pascal void TScrollerScrollBar::WriteRes(ViewRsrcHandle theResource,
  1597.                                          Ptr& itsParams)// override 
  1598. {
  1599.     // We never want to write TScrollerScrollBars.    TScroller will create its own 
  1600. }
  1601.  
  1602. //--------------------------------------------------------------------------------------------------
  1603. #pragma segment MAClose
  1604.  
  1605. pascal void TScrollerScrollBar::Free(void)        // override 
  1606. {
  1607.     if (fScrollers)
  1608.     {
  1609.         CArrayIterator iter(fScrollers);
  1610.         
  1611.         for (ArrayIndex i = iter.FirstIndex(); iter.More(); i = iter.NextIndex())
  1612.         {
  1613.             TScroller* theScroller = (TScroller*)fScrollers->At(i);
  1614.             
  1615.             if (theScroller->fScrollBars[fDirection] == this)
  1616.                 theScroller->HaveScrollBar(NULL, fDirection);
  1617.         
  1618.         }
  1619.         fScrollers = (TList *)(FreeIfObject(fScrollers));
  1620.     }
  1621.  
  1622.     inherited::Free();
  1623. }
  1624.  
  1625. //--------------------------------------------------------------------------------------------------
  1626. #pragma segment MAActivate
  1627.  
  1628. class CScrollBarActivator
  1629. {
  1630.     // Fields
  1631.     TScrollerScrollBar* fScrollerScrollBar;
  1632.     Boolean fEntering;
  1633.  
  1634. public:
  1635.     // Constructor
  1636.     CScrollBarActivator(TScrollerScrollBar* theScrollerScrollBar,
  1637.               Boolean anEntering) :
  1638.         fScrollerScrollBar(theScrollerScrollBar),
  1639.         fEntering(anEntering)
  1640.     {
  1641.     }
  1642.  
  1643.     // Method
  1644.     pascal void SetScrollBar(void);
  1645. };
  1646.  
  1647. #pragma segment MAActivate
  1648.  
  1649. pascal void CScrollBarActivator::SetScrollBar(void)
  1650. {
  1651.     Rect itsQDRect;
  1652.     VRect itsRect;
  1653.  
  1654.     if (fEntering)
  1655.         ShowControl(fScrollerScrollBar->fCMgrControl);
  1656.     else
  1657.     {
  1658.         HideControl(fScrollerScrollBar->fCMgrControl);
  1659.  
  1660.         if (fScrollerScrollBar->IsFocused())
  1661.         {
  1662.             // Get the frame drawn. 
  1663.             itsQDRect = (*(fScrollerScrollBar->fCMgrControl))->contrlRect;
  1664.             fScrollerScrollBar->QDToViewRect(itsQDRect, itsRect);
  1665.             fScrollerScrollBar->Draw(itsRect);
  1666.  
  1667.             // Because Control Manager invalidates the extent of the control but we did direct
  1668.             // drawing in the unclipped area.
  1669.             fScrollerScrollBar->ValidateRgn(qd.thePort->clipRgn);
  1670.         }
  1671.     }
  1672. }
  1673.  
  1674. #pragma segment MAActivate
  1675.  
  1676. pascal void TScrollerScrollBar::Activate(Boolean entering)// override 
  1677. {
  1678.     CScrollBarActivator aScrollBarActivator(this, entering);
  1679.  
  1680.     this->WhileFocused((DoWhileFocusedType) & CScrollBarActivator::SetScrollBar, &aScrollBarActivator, this->Focus());
  1681. }
  1682.  
  1683. //--------------------------------------------------------------------------------------------------
  1684. #pragma segment MAOpen
  1685.  
  1686. pascal void TScrollerScrollBar::AttachScroller(TScroller* itsScroller)
  1687. {
  1688.     if (itsScroller)
  1689.     {
  1690.         fScrollers->Insert(itsScroller);
  1691.         itsScroller->HaveScrollBar(this, fDirection);
  1692.     }
  1693. }
  1694.  
  1695. //--------------------------------------------------------------------------------------------------
  1696. #pragma segment MANonRes
  1697.  
  1698. pascal void TScrollerScrollBar::BeInPort(GrafPtr itsPort)// override 
  1699. {
  1700.     inherited::BeInPort(itsPort);
  1701.     
  1702.     this->SetCMgrVisibility(this->IsActive());
  1703. }
  1704.  
  1705. //--------------------------------------------------------------------------------------------------
  1706. #pragma segment MAScroll
  1707.  
  1708. pascal void TScrollerScrollBar::DoMouseCommand(VPoint& theMouse,
  1709.                                                TToolboxEvent* event,
  1710.                                                Point hysteresis)// override 
  1711. {
  1712.     long sBarDelta = 0;
  1713.     Point theQDMouse;
  1714.  
  1715. #if qDebug
  1716.     this->AssumeFocused();
  1717. #endif
  1718.  
  1719.     theQDMouse = this->ViewToQDPt(theMouse);
  1720.     if (TestControl(fCMgrControl, theQDMouse) == inThumb)
  1721.     {
  1722.         if (TrackControl(fCMgrControl, theQDMouse, NULL) == inThumb)
  1723.         {
  1724.             CArrayIterator iter(fScrollers);
  1725.             
  1726.             // If thumb is dragged to bottom of scroll bar then ensure that
  1727.             // the new long value is set to the maximum long value.
  1728.             if (this->GetVal() == this->GetMax())
  1729.                 fLongVal = fLongMax;
  1730.             else
  1731.                 fLongVal = (this->GetVal() << fBitsToShift);
  1732.                 
  1733.             for (ArrayIndex i = iter.FirstIndex(); iter.More(); i = iter.NextIndex())
  1734.             {
  1735.                 TScroller* theScroller = (TScroller*)fScrollers->At(i);
  1736.                 
  1737.                 sBarDelta += theScroller->ScrollRelative(fDirection, fLongVal);
  1738.             }
  1739.  
  1740.             if (this->Focus() && (sBarDelta != 0))
  1741.                 this->SetLongVal(fLongVal + sBarDelta, kRedraw);
  1742.         }
  1743.     }
  1744.     else
  1745.         inherited::DoMouseCommand(theMouse, event, hysteresis);
  1746. }
  1747.  
  1748. //--------------------------------------------------------------------------------------------------
  1749. #pragma segment MAControlRes
  1750.  
  1751. pascal void TScrollerScrollBar::Draw(const VRect& area)// override 
  1752. {
  1753.     Rect itsRect;
  1754.  
  1755. #if qDebug
  1756.     this->AssumeFocused();
  1757. #endif
  1758.  
  1759.     if (!IsCMgrVisible())
  1760.     {
  1761.         PenNormal();
  1762.         itsRect = (*fCMgrControl)->contrlRect;
  1763.         FrameRect(itsRect);
  1764.     }
  1765.  
  1766.     inherited::Draw(area);
  1767. }
  1768.  
  1769. //--------------------------------------------------------------------------------------------------
  1770. #pragma segment MAScroll
  1771.  
  1772. pascal void TScrollerScrollBar::TrackScrollBar(short partCode)
  1773. {
  1774.     long sBarDelta = 0;;
  1775.     CArrayIterator iter(fScrollers);
  1776.     
  1777.     for (ArrayIndex i = iter.FirstIndex(); iter.More(); i = iter.NextIndex())
  1778.     {
  1779.         TScroller* theScroller = (TScroller*)fScrollers->At(i);
  1780.         
  1781.         sBarDelta += theScroller->ScrollStep(fDirection, partCode);
  1782.     }
  1783.  
  1784.     if (this->Focus())
  1785.         this->DeltaValue(sBarDelta);
  1786. }
  1787.  
  1788. //--------------------------------------------------------------------------------------------------
  1789. #pragma segment MAFields
  1790.  
  1791. pascal void TScrollerScrollBar::Fields(TObject* obj)// override 
  1792. {
  1793.     obj->DoToField("TScrollerScrollBar", NULL, bClass);
  1794.     obj->DoToField("fScrollers", &fScrollers, bObject);
  1795.  
  1796.     inherited::Fields(obj);
  1797. }
  1798.  
  1799.  
  1800.